#include "gametable.h"
#include "gamewindow.h"
#include "gameboardorganizer.h"
#include "player.h"
#include "playerskillobject.h"
#include "infoboard.h"
#include "playeritems.h"
#include "gamephasecontrol.h"
#include "gamedialogmanager.h"
#include "ghostboarditems.h"
#include "gamedialog.h"
#include "ghost.h"
#include "QDebug"
#include "ghostskill.h"

/*

  This class includes following stuff:
            Organizer:
                TileBoard x 1 includes VillageTile x 9
                GhostBoard x 4 includes GhostSlot x 3 for each
                PlayerStatusBoard x 4 includes Head x 1 & Status x 1 for each
                CurrentPlayerBoard x 1 includes a lot.
                GhostInfo?

            Item:
                VillageTile x 9
                GhostSlot x 12
                Head x 4
                Status x 4

*/


GameTable::GameTable(GameWindow* window)
    :QGraphicsObject(0), _window(window)
{
    moveBy(0, -10);
    //create players
    createPlayers();
    //set players' skills
    setPlayerSkills();
    //create item manager
    iManager = new ItemManager(this);

    //table center board
    cTable = new CenterTable(this);
    cTable->moveBy(0,0);

    //table left board
    lTable = new LeftTable(this);
    lTable->moveBy(-350, -CenterTable::HEIGHT/2+(lTable->boundingRect().height()-10)/2);

    //table right board
    rTable = new RightTable(this);
    rTable->moveBy(350, -CenterTable::HEIGHT/2+(lTable->boundingRect().height()-10)/2);

    //table bottom board
    bTable = new BottomTable(this);

    //phase table
    phaseTable = new GamePhaseControl(this);
    phaseTable->moveBy(0, -CenterTable::OUTHEIGHT/2-PhaseConsoleItem::HEIGHT/2);
}

QRectF GameTable::boundingRect() const{
    return QRectF();
}

void GameTable::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){

}

QList<Player*> GameTable::getPlayerList(){
    return players;
}

ItemManager* GameTable::getItemManager(){
    return iManager;
}

QList<GhostBoard*> GameTable::getGhostBoards(){
    return cTable->getGhostBoards();
}

void GameTable::createPlayers(){
    for(int i = 0; i<4; i++){
        Player* p = new Player(this);
        players << p;
    }
}

void GameTable::setPlayerSkills(){
    PlayerSkillObject* bs = new BottomLessSkill(this);
    PlayerSkillObject* dp = new DancePeaksSkill(this);
    PlayerSkillObject* tw = new TwinWindsSkill(this);
    this->getPlayerList().at(0)->setPlayerSkill(bs);
    this->getPlayerList().at(1)->setPlayerSkill(dp);
    this->getPlayerList().at(2)->setPlayerSkill(tw);

}

GameWindow* GameTable::getGameWindow(){
    return _window;
}

InfoBoard * GameTable::getInfoBoard()
{
    return lTable->getInfoBoard();
}
DeckBoard * GameTable::getDeckBoard()
{
    return rTable->getDeckBoard();
}

Ghost* GameTable::getDeckCurrentGhost(){
    return rTable->getDeckBoard()->currentGhost();
}

//need to be modified
Player* GameTable::getCurrentPlayer(){
    return this->getPlayerList().at(2);
}
//need to be modified
void GameTable::updateCurrentPlayer(Player *pl){
    this->getPlayerList().replace(0,pl);
}

void GameTable::check_ghost_action(){
    //QList<GhostSlot*> slot = getCurrentPlayer()->getGhostBoard()->getSlots();
}


//need to be modified
void GameTable::roll_curse_dice()
{

}

void GameTable::ghost_arrival()
{
    //ghost arrival
    rTable->getDeckBoard()->flip();
    GameSlotRequestDialog* ref = getGameWindow()->getDialogs()->getSlotRequestDialog();
    //temp connect for use, disconnect after finished
    connect(cTable, SIGNAL(clicked(GhostSlot*)), ref, SLOT(receiveClickOnSlot(GhostSlot*)));
    GhostSlot* slot = getGameWindow()->getDialogs()->askSlotRequestDialog();
    disconnect(cTable, SIGNAL(clicked(GhostSlot*)), ref, SLOT(receiveClickOnSlot(GhostSlot*))); 
    if(slot!=0)
    {
        slot->setGhostCard(getDeckCurrentGhost());
        nGhost = getDeckCurrentGhost();
        rTable->getDeckBoard()->pop();
        GhostBoard* gboard = (GhostBoard*)slot->getParentBoard();
        nGhost->setGhostBoard(gboard);
        // ghost arrival action (activate the left skill)
        qDebug() << Ghost::SkillsToString(nGhost->getSkillL());
        if( !nGhost->getSkillL().testFlag( NO_SKILL ) )
        {
            GhostSkillList * skills = nGhost->getSkillObjectL();
            skills->invoke_all();
        }
    }
}

void GameTable::taoist_act()
{

}

void GameTable::exo_act()
{

}

//ITEM MANAGER
ItemManager::ItemManager(GameTable* gt)
{
    defalut_TaoNum = 4;
    DiceNum = 3;
    RemainTaoNums << defalut_TaoNum << defalut_TaoNum << defalut_TaoNum
                  << defalut_TaoNum << defalut_TaoNum;
    plist = gt->getPlayerList();
    connect(gt->getCurrentPlayer(),SIGNAL(taoChanged()),this,SLOT(TaoNumUpdate()));
}

QList<int> ItemManager::getRemainTaoNums()
{
    return RemainTaoNums;
}

QList<int> ItemManager::getCurrentTaoNums()
{
    return CurrentTaoNums;
}

void ItemManager::TaoNumUpdate()
{
    int playerRedTao = 0;
    int plyaerYellowTao = 0;
    int playerGreenTao = 0;
    int playerBlackTao = 0;
    int playerBlueTao = 0;
    CurrentTaoNums.clear();
    for(int i=0;i<plist.size();i++){
        playerRedTao += plist.at(i)->getResistR();
        plyaerYellowTao += plist.at(i)->getResistY();
        playerGreenTao += plist.at(i)->getResistG();
        playerBlackTao += plist.at(i)->getResistBlack();
        playerBlueTao += plist.at(i)->getResistBlue();
    }
    CurrentTaoNums << playerRedTao << plyaerYellowTao << playerGreenTao
                     << playerBlackTao << playerBlueTao;

    for(int i=0;i<RemainTaoNums.size();i++){
        RemainTaoNums.replace(i,defalut_TaoNum-CurrentTaoNums.at(i));
    }
    qDebug() << "Remain Tao:" << RemainTaoNums;

}

int ItemManager::getDiceNum()
{
    return DiceNum;
}
void ItemManager::setDiceNum(int n)
{
    DiceNum = n;
}
